package com.yunmell.wechat.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import com.alibaba.fastjson2.JSON;
import com.yunmell.wechat.util.json.WXBizJsonMsgCrypt;
import com.yunmell.wechat.util.xml.WXBizMsgCrypt;
import com.yunmell.wechat.util.xml.XMLParse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Document;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 企微数据、指令回调
 *
 * @author bobo
 * @since 2023/11/14
 */
@RestController
@RequestMapping("/je/wechat/callback/verify")
public class WechatCallbackController {

	String sToken = "回调配置的token";
	String sEncodingAESKey = "回调配置的EncodingAESKey";
	String SuiteID = "应用ID";
	String CorpID = "企业ID";

	Logger logger = LoggerFactory.getLogger(WechatCallbackController.class);

	@RequestMapping(value = "data", method = {RequestMethod.GET, RequestMethod.POST})
	public void dataVerify(HttpServletRequest request, HttpServletResponse response) {
		/*
		------------使用示例一：验证回调URL---------------
		*企业开启回调模式时，企业微信会向验证url发送一个get请求
		假设点击验证时，企业收到类似请求：
		* GET /cgi-bin/wxpush?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D
		* HTTP/1.1 Host: qy.weixin.qq.com

		接收到该请求时，企业应
		1.解析出Get请求的参数，包括消息体签名(msg_signature)，时间戳(timestamp)，随机数字串(nonce)以及企业微信推送过来的随机加密字符串(echostr),
		这一步注意作URL解码。
		2.验证消息体签名的正确性
		3. 解密出echostr原文，将原文当作Get请求的response，返回给企业微信
		第2，3步可以用企业微信提供的库函数VerifyURL来实现。

		*/

		logger.info("请求方式 {}", request.getMethod());

		if ("GET".equalsIgnoreCase(request.getMethod())) {
			try {
				String msgSignature = request.getParameter("msg_signature");
				String timestamp = request.getParameter("timestamp");
				String nonce = request.getParameter("nonce");
				String echostr = request.getParameter("echostr");

				if (StrUtil.isBlank(msgSignature) || StrUtil.isBlank(timestamp) || StrUtil.isBlank(nonce) || StrUtil.isBlank(echostr)) {
					logger.error("参数缺失 msgSignature={} timestamp={} nonce={} echostr={}", msgSignature, timestamp, nonce, echostr);
				}

				WXBizJsonMsgCrypt wxcpt = new WXBizJsonMsgCrypt(sToken, sEncodingAESKey, SuiteID);
				String sEchoStr = wxcpt.VerifyURL(msgSignature, timestamp, nonce, echostr);
				logger.info("sEchoStr {}", sEchoStr);
				response.setContentType("text/plain");
				response.setCharacterEncoding("UTF-8");
				response.getWriter().write(sEchoStr);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if ("POST".equalsIgnoreCase(request.getMethod())) {
			try {
				String msgSignature = request.getParameter("msg_signature");
				String timestamp = request.getParameter("timestamp");
				String nonce = request.getParameter("nonce");
				String echostr = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

				if (StrUtil.isBlank(msgSignature) || StrUtil.isBlank(timestamp) || StrUtil.isBlank(nonce) || StrUtil.isBlank(echostr)) {
					logger.error("参数缺失 msgSignature={} timestamp={} nonce={} echostr={}", msgSignature, timestamp, nonce, echostr);
				}

				WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, CorpID);
				String sEchoStr = wxcpt.DecryptMsg(msgSignature, timestamp, nonce, echostr);
				logger.info("sEchoStr {}", sEchoStr);
				response.setContentType("text/plain");
				response.setCharacterEncoding("UTF-8");
				response.getWriter().write("success");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@RequestMapping(value = "command", method = {RequestMethod.GET, RequestMethod.POST})
	public void commandVerify(HttpServletRequest request, HttpServletResponse response) {
		/*
		------------使用示例一：验证回调URL---------------
		*企业开启回调模式时，企业微信会向验证url发送一个get请求
		假设点击验证时，企业收到类似请求：
		* GET /cgi-bin/wxpush?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D
		* HTTP/1.1 Host: qy.weixin.qq.com

		接收到该请求时，企业应
		1.解析出Get请求的参数，包括消息体签名(msg_signature)，时间戳(timestamp)，随机数字串(nonce)以及企业微信推送过来的随机加密字符串(echostr),
		这一步注意作URL解码。
		2.验证消息体签名的正确性
		3. 解密出echostr原文，将原文当作Get请求的response，返回给企业微信
		第2，3步可以用企业微信提供的库函数VerifyURL来实现。

		*/

		logger.info("请求方式 {}", request.getMethod());

		if ("GET".equalsIgnoreCase(request.getMethod())) {
			try {
				String msgSignature = request.getParameter("msg_signature");
				String timestamp = request.getParameter("timestamp");
				String nonce = request.getParameter("nonce");
				String echostr = request.getParameter("echostr");

				if (StrUtil.isBlank(msgSignature) || StrUtil.isBlank(timestamp) || StrUtil.isBlank(nonce) || StrUtil.isBlank(echostr)) {
					logger.error("参数缺失 msgSignature={} timestamp={} nonce={} echostr={}", msgSignature, timestamp, nonce, echostr);
				}

				WXBizJsonMsgCrypt wxcpt = new WXBizJsonMsgCrypt(sToken, sEncodingAESKey, SuiteID);
				String sEchoStr = wxcpt.VerifyURL(msgSignature, timestamp, nonce, echostr);
				logger.info("sEchoStr {}", sEchoStr);
				response.setContentType("text/plain");
				response.setCharacterEncoding("UTF-8");
				response.getWriter().write(sEchoStr);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if ("POST".equalsIgnoreCase(request.getMethod())) {
			try {

				String msgSignature = request.getParameter("msg_signature");
				String timestamp = request.getParameter("timestamp");
				String nonce = request.getParameter("nonce");
				String echostr = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

				if (StrUtil.isBlank(msgSignature) || StrUtil.isBlank(timestamp) || StrUtil.isBlank(nonce) || StrUtil.isBlank(echostr)) {
					logger.error("参数缺失 msgSignature={} timestamp={} nonce={} echostr={}", msgSignature, timestamp, nonce, echostr);
				}

				WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, CorpID);
				String sEchoStr = wxcpt.DecryptMsg(msgSignature, timestamp, nonce, echostr);
				logger.info("sEchoStr {}", sEchoStr);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
